const User = require('@/models/user.models');
const Role = require('@/models/role.models');
const userRole = require('@/models/userRole.models');
const { generateToken } = require('@/middleware/jwt.middleware')
const { frontDecrypt, backEncrypt, backDecrypt } = require('@/utils/crypto')
const { createResponse, createErrorResponse } = require('@/utils/tool')


/**
 * 创建用户
 * @param {*} info 用户详情
 * @param {*} info.account 账号
 * @param {*} info.password 密码
 * @param {*} info.nickname 昵称
 * @param {*} info.email 邮箱
 * @param {*} info.phoneNumber 手机号
 * @param {*} info.avatar 头像
 * @param {*} info.roleIds 角色ID
 * @param {*} frontCryptoState 前端加密状态
 */
async function createUser(info, frontCryptoState) {
  try {
    let { account, password, nickname, email, phoneNumber, avatar, roleIds } = info
    // 检查是否已经存在相同的账号
    const existingUser = await User.findOne({
      where: {
        account,
        deletedAt: null
      }
    });
    if (existingUser) {
      return createResponse({ code: 400, message: "账号已存在" })
    }

    // 密码在前端是否加密
    if (frontCryptoState || frontCryptoState == 'true') {
      password = frontDecrypt(password)
    }
    // 后端执行加密
    password = backEncrypt(password)
    const user = await User.create({
      account,
      password,
      nickname,
      email,
      phoneNumber,
      avatar,
    });
    // 更新角色
    await user.setRoles(roleIds);


    let userInfo = user.toJSON()
    userInfo.roles = await getRolesByUserId(user.id)
    delete userInfo.password
    return createResponse({ message: "创建成功", code: 200, data: userInfo })
  } catch (error) {
    return createErrorResponse(error)
  }
}

/**
 * 通过ID查询用户
 * @param {*} userId 
 */
async function getUserById(userId) {
  try {
    const user = await User.findByPk(userId);
    if (user) {
      let userInfo = user.toJSON()
      userInfo.roles = await getRolesByUserId(user.id)
      delete userInfo.password
      return createResponse({ message: "请求成功", code: 200, data: { userInfo } })
    } else {
      return createResponse({ message: "用户不存在", code: 401 })
    }
  } catch (error) {
    return createErrorResponse(error)
  }
}

/**
 * 查询所有用户数据
 * @param {*} order 排序字段 ASC/DESC
 * @returns 
 */
async function getAllUsers(order) {
  try {
    const users = await User.findAll({
      order: [['createdAt', order ?? 'ASC']],
      where: {
        deletedAt: null
      }
    });
    let list = await Promise.all(users.map(async (user) => {
      let userInfo = user.toJSON()
      userInfo.roles = await getRolesByUserId(userInfo.id)
      delete userInfo.password
      return userInfo
    }))
    return createResponse({ message: "请求成功", code: 200, data: { list, total: users.length } })
  } catch (error) {
    return createErrorResponse(error)
  }
}

/**
 * 分页查询用户
 * @param {*} page 页码
 * @param {*} pageSize 数量
 * @param {*} order 排序字段 ASC/DESC
 * @returns 
 */
async function getPaginatedUsers(page = 1, pageSize = 10, order) {
  try {
    const offset = (page - 1) * pageSize;
    const limit = Number(pageSize);

    const users = await User.findAndCountAll({
      offset,
      limit,
      order: [['createdAt', order ?? 'ASC']],
      where: {
        deletedAt: null
      }
    });
    let list = await Promise.all(users.rows.map(async (user) => {
      let userInfo = user.toJSON()
      userInfo.roles = await getRolesByUserId(user.id)
      delete userInfo.password
      return userInfo
    }))
    return createResponse({ message: "请求成功", code: 200, data: { list, total: users.count } })
  } catch (error) {
    return createErrorResponse(error)
  }
}

/**
 * 更改用户信息
 * @param {*} userId 用户ID
 * @param {*} updates 用户信息
 * @param {*} frontCryptoState 前端加密状态  
 * @returns
 */
async function updataUser(userId, updates, frontCryptoState) {
  try {
    const user = await User.findByPk(userId);
    if (updates.password) {
      // 密码在前端是否加密
      if (frontCryptoState || frontCryptoState == 'true') {
        updates.password = frontDecrypt(updates.password)
      }
      // 后端执行加密
      updates.password = backEncrypt(updates.password)
    }
    if (user) {
      Object.assign(user, updates);
      await user.save();
      delete user.password
      // 更新角色
      if (updates.roleIds) {
        // 手动删除现有的角色关联
        await user.setRoles([])
        await user.setRoles(updates.roleIds)
      }
      let data = user.toJSON()
      data.roles = await getRolesByUserId(user.id)
      return createResponse({ message: "更新成功", code: 200, data })
    } else {
      return createResponse({ message: "用户不存在", code: 401, data: {} })
    }
  } catch (error) {
    return createErrorResponse(error)
  }
}


/**
 * 通过ID删除
 * @param {*} userId 
 */
async function deleteUser(userId) {
  try {
    const user = await User.findByPk(userId);
    if (user) {
      await user.destroy(); // 假删除
      // await user.destroy({ force: true }); // 强制删除
      return createResponse({ message: "删除成功", code: 200 })
    } else {
      return createResponse({ message: "用户不存在", code: 401 })
    }
  } catch (error) {
    return createErrorResponse(error)
  }
}

/**
 * 更改密码
 * @param {*} userId 用户id
 * @param {*} oldPassword 旧密码
 * @param {*} newPassword 新密码
 * @param {*} frontCryptoState 前端是否加密
 * @returns 
 */
async function updataUserPassword(userId, oldPassword, newPassword, frontCryptoState) {
  try {
    const user = await User.findByPk(userId);
    if (!user) {
      return createResponse({ message: "用户不存在", code: 401 })
    }
    // 如果前端加密
    if (frontCryptoState || frontCryptoState == 'true') {
      oldPassword = frontDecrypt(oldPassword)
    }
    if (user.password == oldPassword) {
      return createResponse({ message: "旧密码错误", code: 401, data: {} })
    }
    user.password = backEncrypt(newPassword)
    await user.save();
    return createResponse({ message: "更新成功", code: 200 })
  } catch (error) {
    return createErrorResponse(error)
  }
}

/**
 * 登录
 * @param {*} account 账号
 * @param {*} password 密码
 * @param {*} frontCryptoState 前端是否加密
 */
async function findByCredentials(account, password, frontCryptoState) {
  try {
    const user = await User.findOne({ where: { account } });
    if (!user) {
      return createResponse({ message: "用户名不存在", code: 401 })
    }

    // 密码在前端是否加密
    if (frontCryptoState || frontCryptoState == 'true') {
      password = frontDecrypt(password)
    }
    // 后端执行加密
    password = backEncrypt(password)
    if (password !== user.password) {
      return createResponse({ message: "用户名或密码错误", code: 401 })
    }
    let userInfo = user.toJSON()
    userInfo.roles = await getRolesByUserId(user.id)
    delete userInfo.password
    let token = generateToken(userInfo)

    return createResponse({ message: "登录成功", code: 200, data: { userInfo, token } })
  } catch (error) {
    return createErrorResponse(error)
  }
};

/**
 * 通过ID获取用户绑定角色
 * @param {number} userId 用户ID
 * @returns {Object} 角色信息列表
 */
async function getRolesByUserId(userId) {
  try {
    const user = await User.findByPk(userId, {
      include: [
        {
          model: Role,
          as: 'Roles',
          attributes: ['id', 'name', 'description']
        }
      ]
    });
    if (!user) {
      return []
    }
    let roles = user.toJSON().Roles
    return roles.map((role) => {
      return {
        id: role.id,
        name: role.name,
        description: role.description,
      }
    }); // 返回用户的角色列表
  } catch (error) {
    console.log('error :>> ', error);
    return []
  }
}

module.exports = {
  createUser,
  getAllUsers,
  getPaginatedUsers,
  getUserById,
  updataUser,
  updataUserPassword,
  deleteUser,
  findByCredentials
}